home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************
- * fljpeg.c: FBM Release 1.2 24-Mar-93 Michael Mauldin
- *
- * Copyright (C) 1993 by Michael Mauldin. Permission is granted
- * to use this file in whole or in part for any purpose, educational,
- * recreational or commercial, provided that this copyright notice
- * is retained unchanged. This software is available to all free of
- * charge by anonymous FTP and in the UUNET archives.
- *
- * This code is based on example.c from the JPEG library.
- *
- * fljpeg.c:
- *
- * CONTENTS
- * read_jpeg (image, rfile, mstr, mlen)
- * write_jpeg (image, wfile)
- *
- * EDITLOG
- * LastEditDate = Mon Jun 25 00:18:04 1990 - Michael Mauldin
- * LastFileName = /usr2/mlm/src/misc/fbm/fljpeg.c
- *
- * HISTORY
- * 31-Mar-93 Michael Mauldin (mlm@cs.cmu.edu) Carnegie Mellon
- * Created.
- *****************************************************************/
-
- # include <stdio.h>
- # include <math.h>
- # include "fbm.h"
-
- # define RED 0
- # define GRN 1
- # define BLU 2
-
- static FBM *fbm_image; /* Global to allow allow access to methods */
- static int row;
-
- #ifndef lint
- static char *fbmid =
- "$FBM fljpeg.c <1.2> 24-Mar-93 (C) 1993 by Michael Mauldin, source \
- code available free from MLM@CS.CMU.EDU and from UUNET archives$";
- #endif
-
- # ifdef DO_JPEG
- # include <setjmp.h>
- # include <sys/types.h>
- # include "jinclude.h"
-
-
- /*================ Compressor ================*/
-
- void input_init (cinfo)
- compress_info_ptr cinfo;
- {
- /* The fields are initialized in write_jpeg */
- }
-
-
- /*
- * This function is called repeatedly and must supply the next row of pixels
- * on each call. The rows MUST be returned in top-to-bottom order if you want
- * your JPEG files to be compatible with everyone else's.
- */
-
- void get_input_row (cinfo, pixel_row)
- compress_info_ptr cinfo;
- JSAMPARRAY pixel_row;
- /* Read next row of pixels into pixel_row[][] */
- {
- /* This example shows how you might read RGB data (3 components)
- * from an input file in which the data is stored 3 bytes per pixel
- * in left-to-right, top-to-bottom order.
- */
- register FILE * infile = cinfo->input_file;
- register JSAMPROW obm;
- register unsigned char *ibm;
- register int k;
- register long col;
-
- if (row >= fbm_image->hdr.rows) return;
-
- /* Copy a row from each plane into the appropriate pixel_row */
- for (k=0; k<cinfo->input_components; k++)
- { obm = pixel_row[k];
- ibm = &fbm_image->bm[k * fbm_image->hdr.plnlen +
- row * fbm_image->hdr.rowlen];
-
- for (col = 0; col < cinfo->image_width; col++)
- { *obm++ = (JSAMPLE) *ibm++; }
- }
-
- row++;
- }
-
- void input_term (cinfo)
- compress_info_ptr cinfo;
- /* Finish up at the end of the input */
- {
- /* no work to do */
- }
-
- /*
- * This routine must determine what output JPEG file format is to be written,
- */
-
- void c_ui_method_selection (cinfo)
- compress_info_ptr cinfo;
- {
- /* If the input is gray scale, generate a monochrome JPEG file. */
- if (cinfo->in_color_space == CS_GRAYSCALE)
- j_monochrome_default(cinfo);
-
- /* For now, always select JFIF output format. */
- jselwjfif(cinfo);
- }
-
- /****************************************************************
- * write_jpeg: Set up methods and call compressor
- ****************************************************************/
-
- write_jpeg (image, wfile, quality)
- FBM *image;
- FILE *wfile;
- int quality;
- {
- struct Compress_info_struct cinfo;
- struct Compress_methods_struct c_methods;
- struct External_methods_struct e_methods;
-
- /* Global for get_input_row */
- fbm_image = image;
-
- /* Initialize the system-dependent method pointers. */
- cinfo.methods = &c_methods; /* links to method structs */
- cinfo.emethods = &e_methods;
- jselerror(&e_methods); /* select std error/trace message routines */
- jselmemmgr(&e_methods); /* select std memory allocation routines */
-
- /*-------- Code that normally goes in input_init --------*/
- cinfo.image_width = image->hdr.cols; /* width in pixels */
- cinfo.image_height = image->hdr.rows; /* height in pixels */
- cinfo.input_components = image->hdr.planes; /* or 1 for grayscale */
-
- if (cinfo.input_components == 1)
- { cinfo.in_color_space = CS_GRAYSCALE; }
- else
- { cinfo.in_color_space = CS_RGB; }
-
- cinfo.data_precision = image->hdr.physbits; /* bits/pixel comp. value */
-
- row = 0;
- /*---------------------------------------------------*/
-
- /* Here, set up pointers to your own routines for input data handling
- * and post-init parameter selection.
- */
- c_methods.input_init = input_init; /* now a nop */
- c_methods.get_input_row = get_input_row;
- c_methods.input_term = input_term;
- c_methods.c_ui_method_selection = c_ui_method_selection;
-
- /* Set up default JPEG parameters in the cinfo data structure. */
- j_c_defaults(&cinfo, quality, TRUE);
-
- cinfo.input_file = NULL; /* if no actual input file involved */
- cinfo.output_file = wfile;
-
- /* Here we go! */
- jpeg_compress(&cinfo);
- }
-
- /* ================ Decompressor ================*/
-
- /* These static variables are needed by the error routines. */
- static jmp_buf setjmp_buffer; /* for return to caller */
- static external_methods_ptr emethods; /* for access to message_parm */
-
- /* This routine is used for any and all trace, debug, or error printouts
- * from the JPEG code. The parameter is a printf format string; up to 8
- * integer data values for the format string have been stored in the
- * message_parm[] field of the external_methods struct.
- */
-
- void trace_message (msgtext)
- char *msgtext;
- {
- fprintf(stderr, msgtext,
- emethods->message_parm[0], emethods->message_parm[1],
- emethods->message_parm[2], emethods->message_parm[3],
- emethods->message_parm[4], emethods->message_parm[5],
- emethods->message_parm[6], emethods->message_parm[7]);
- fprintf(stderr, "\n"); /* there is no \n in the format string! */
- }
-
- /*
- * The error_exit() routine should not return to its caller. The default
- * routine calls exit(), but here we assume that we want to return to
- * read_JPEG_file, which has set up a setjmp context for the purpose.
- * You should make sure that the free_all method is called, either within
- * error_exit or after the return to the outer-level routine.
- */
-
- void error_exit (msgtext)
- char *msgtext;
- {
- trace_message(msgtext); /* report the error message */
- (*emethods->free_all) (); /* clean up memory allocation & temp files */
- longjmp(setjmp_buffer, 1); /* return control to outer routine */
- }
-
- /****************************************************************
- * output_init;
- ****************************************************************/
-
-
- void output_init (cinfo)
- decompress_info_ptr cinfo;
- { int rowlen;
-
- /* Set image size */
- fbm_image->hdr.rows = cinfo->image_height;
- fbm_image->hdr.cols = cinfo->image_width;
- fbm_image->hdr.bits = cinfo->data_precision;
- fbm_image->hdr.physbits = 8;
- fbm_image->hdr.planes = (cinfo->out_color_space == CS_GRAYSCALE) ? 1 : 3;
-
- /*
- * Check for too many bits of precision. In the future, we
- * should just truncate to the 8 highest bits in this case.
- */
-
- if (cinfo->data_precision > 8)
- { char mbuf[256];
- sprintf (mbuf, "error:input has %d bits precision, can only handle 8\n",
- cinfo->data_precision);
- error_exit (mbuf);
- }
-
- /* Make sure rowlen is extended to an even number of bytes */
- if ((rowlen = fbm_image->hdr.cols) & 1) rowlen++;
- fbm_image->hdr.rowlen = rowlen;
- fbm_image->hdr.plnlen = rowlen * fbm_image->hdr.rows;
-
- /* ALways unmapped output */
- fbm_image->hdr.clrlen = 0;
-
- /* Miscellaneous annotations */
- fbm_image->hdr.aspect = 1.0;
- fbm_image->hdr.title[0] = '\0';
- strcpy (fbm_image->hdr.credits, "via JPEG");
-
- alloc_fbm (fbm_image);
-
- row = 0; /* Global variable used in put_pixel_rows */
- }
-
- /*
- * This routine is called if and only if you have set cinfo->quantize_colors
- * to TRUE. We don't need this for FBM.
- */
-
- void put_color_map ()
- {
- fprintf(stderr, "put_color_map called: there's a bug here somewhere!\n");
- }
-
- /*****************************************************************
- * put_pixel_rows: Called with 1 or more rows in top to bottom order
- *****************************************************************/
-
- void put_pixel_rows (cinfo, num_rows, pixel_data)
- decompress_info_ptr cinfo;
- int num_rows;
- JSAMPIMAGE pixel_data;
- { register FILE * outfile = cinfo->output_file;
- register JSAMPROW ibm;
- register unsigned char *obm;
- register int i, j, k;
-
- for (j = 0; j < num_rows && row < fbm_image->hdr.rows; j++, row++)
- { for (k=0; k < fbm_image->hdr.planes; k++)
- { ibm = pixel_data[k][j];
- obm = &fbm_image->bm[k * fbm_image->hdr.plnlen +
- row * fbm_image->hdr.rowlen];
-
- for (i = cinfo->image_width; i > 0; i--, ibm++)
- { *obm++ = GETJSAMPLE (*ibm); }
- }
- }
- }
-
- void output_term ()
- {
- /* no work to do */
- }
-
- /*****************************************************************
- * Now we have overall control and parameter selection routines.
- *****************************************************************/
-
- void
- d_ui_method_selection (cinfo)
- decompress_info_ptr cinfo;
- {
- /* if grayscale input, force grayscale output; */
- /* else leave the output colorspace as set by main routine. */
- if (cinfo->jpeg_color_space == CS_GRAYSCALE)
- cinfo->out_color_space = CS_GRAYSCALE;
-
- /* select output routines */
- cinfo->methods->output_init = output_init;
- cinfo->methods->put_color_map = put_color_map;
- cinfo->methods->put_pixel_rows = put_pixel_rows;
- cinfo->methods->output_term = output_term;
- }
-
- /*****************************************************************
- * OK, here is the main function that actually causes everything to happen.
- * We assume here that all decompression parameters can be default values.
- * The routine returns 1 if successful, 0 if not.
- *****************************************************************/
-
- read_jpeg (image, rfile)
- FBM *image;
- FILE *rfile;
- {
- struct Decompress_info_struct cinfo;
- struct Decompress_methods_struct dc_methods;
- struct External_methods_struct e_methods;
-
- fbm_image = image;
-
- /* Set input file from caller and specify no output files */
- cinfo.input_file = rfile;
- cinfo.output_file = NULL; /* if no actual output file involved */
-
- /* Initialize the system-dependent method pointers. */
- cinfo.methods = &dc_methods; /* links to method structs */
- cinfo.emethods = &e_methods;
-
- /* Here we supply our own error handler; compare to use of standard error
- * handler in the previous write_JPEG_file example.
- */
- emethods = &e_methods; /* save struct addr for possible access */
- e_methods.error_exit = error_exit; /* supply error-exit routine */
- e_methods.trace_message = trace_message; /* supply trace-message routine */
- e_methods.trace_level = 0; /* default = no tracing */
- e_methods.num_warnings = 0; /* no warnings emitted yet */
- e_methods.first_warning_level = 0; /* display first corrupt-data warning */
- e_methods.more_warning_level = 3; /* but suppress additional ones */
-
- /* prepare setjmp context for possible exit from error_exit */
- if (setjmp(setjmp_buffer))
- { fclose(cinfo.input_file);
- return (0);
- }
-
- jselmemmgr(&e_methods);
- dc_methods.d_ui_method_selection = d_ui_method_selection;
- j_d_defaults(&cinfo, TRUE);
- jselrjfif(&cinfo);
-
- /* Here we go! */
- jpeg_decompress(&cinfo);
-
- fclose(cinfo.input_file);
-
- return (1);
- }
- # else
-
- /****************************************************************
- * stubs for reading and writing JPEG, since the library isn't loaded
- ****************************************************************/
-
- write_jpeg (image, wfile, quality)
- FBM *image;
- FILE *wfile;
- int quality;
- {
- fprintf (stderr, "JPEG support was not compiled into this executable\n");
- exit (1);
- }
-
- read_jpeg (image, rfile)
- FBM *image;
- FILE *rfile;
- {
- fprintf (stderr, "JPEG support was not compiled into this executable\n");
- exit (1);
- }
- # endif
-